Como convertir un observable en una promesa para que se comporte de manera sincrona.
NOTA: Es mas recomendable hacer uso de Chain Observables en vez de convertir un observable en una promesa
Para este ejemplo tenemos un servicio como el siguiente (que devuelve un observable):
constructor(private http:HttpClient) { }
getInfo(){
return this.http.get<messageRequest[]>("http://127.0.0.1:8080/api/members")
}
El servicio lo usamos en este componente de la siguiente manera:
constructor( private httpView: HttpViewService ) {
}
ngOnInit() {
this.httpView.getInfo().subscribe(data => this.messageObject = data)
console.log("TERMINADO !!!")
}
Al ejecutarlo lo que ocurre es que el observable (que se encarga de traer la información del endpoint de backend) termina su ejecución mas tarde que el console.log que hay justo despues.
De manera que la información que devuelve el observable se ve despues que la salida del propio console.log
Para evitar este comportamiento podemos convertir el Observable en una Promesa usando firstValueFrom, el código quedaría tal que así:
constructor( private httpView: HttpViewService ) {
}
async ngOnInit() {
this.messageObject = await firstValueFrom(this.httpView.getInfo());
console.log("TERMINADO !!!")
}
Y ahora al hacer la ejecución el console.log no se ejecutará hasta que la promesa termine
Tenemos que tener en cuenta las siguientes partes del código que han cambiado, para hacer la llamada sincrona, async, await, firstValueFrom:
Si necesitamos capturar los errores que se puedan producir en la promesa tenemos que hacerlo de la siguiente manera:
async ngOnInit() {
await firstValueFrom(this.httpView.getInfo()).then(
data => this.messageObject = data
).catch(
(error) => console.log("Error")
);
console.log("TERMINADO !!!")
}
Angular | Observable | Promise | firstValueFrom